package com.kum.service.oss;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.kum.pojo.File;
import com.kum.pojo.down_ret;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class OSSClient {
    private OSS client = null;
    private String endpoint = "endpoint";
    private String accessKeyId = "accessKeyId";
    private String accessKeySecret = "accessKeySecret";
    public String bucketName = "bucketName";
    public static String basePath = "user_space/";

    public OSSClient() {
        client = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * 上传文件
     *
     * @param path 目标路径
     * @param b    文件数据
     */
    public void putFile(String path, byte[] b) {
        path = basePath + path;
        client.putObject(bucketName, path, new ByteArrayInputStream(b));
    }

    /**
     * 获得文件列表
     *
     * @param path    目标文件路径
     * @param onlyDir 如果为真那么就只返回文件夹，反之返回全部
     */
    public String getFileList(String path, boolean onlyDir) {
        path = basePath + path;
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
        listObjectsRequest.setDelimiter("/");
        listObjectsRequest.setPrefix(path);
        ObjectListing listObjects = client.listObjects(listObjectsRequest);

        //getCommonPrefixes 是获取文件夹，而getObjectSummaries 是获取文件
        List<String> prefixes = listObjects.getCommonPrefixes();
        ArrayList<File> files = new ArrayList<>();

        for (String prefixe : prefixes) {
            if (!onlyDir && (prefixe.contains("/回收站/") || prefixe.contains("/隐私空间/"))
                    || (onlyDir && prefixe.contains("/回收站/"))) {
                continue;

            }
            files.add(new File(prefixe, null, null));
        }
        if (!onlyDir) {
            List<OSSObjectSummary> Summaries = listObjects.getObjectSummaries();
            for (OSSObjectSummary Summary : Summaries) {
                files.add(new File(Summary.getKey(), Summary.getSize(), Summary.getLastModified()));
            }
        }
        return JSON.toJSONString(files);
    }

    /**
     * 获得对应格式的文件列表
     *
     * @param userId 用户 ID
     * @param format 格式类型
     * @return
     */
    public String getFileFormatList(String userId, String format) {
        String[] typeArr = getFileTypeArr(format);
        System.out.println(typeArr.length);
        List<OSSObjectSummary> sums = getAllFileList(userId);
        List<File> list = new ArrayList<>();
        for (OSSObjectSummary sum : sums) {
            String key = sum.getKey();
            if (key.contains("回收站") || key.contains("隐私空间")) continue;
            for (String t :
                    typeArr) {
                String type = key.substring(key.length() - t.length(), key.length());
                if (type.contains(t)) {
                    list.add(new File(key, sum.getSize(), sum.getLastModified()));
                    break;
                }

            }


        }
        return JSON.toJSONString(list);
    }

    public String selectFile(String userId, String name) {
        System.out.println(userId);
        List<OSSObjectSummary> sums = getAllFileList(userId);
        List<File> list = new ArrayList<>();
        for (OSSObjectSummary sum : sums) {
            String key = sum.getKey();
            String sub = key.substring(key.lastIndexOf("/"), key.length());
            if (sub.length() < 2) continue;
            if (sub.contains(name)) {
                list.add(new File(key, sum.getSize(), sum.getLastModified()));
            }
        }
        return JSON.toJSONString(list);


    }

    /**
     * 删除文件
     * <p>如果是文件，删除的同时会移动到用户的回收站目录</p>
     * @param paths 待删除文件列表
     * @param userId 用户 ID
     */
    public void deleteFile(List<String> paths, String userId) {
        for (String path : paths) {
            if (path.contains(userId)) {
                path = basePath + path;
            } else {
                path = basePath + userId + path;

            }
            if (path.substring(path.length() - 1).equals("/")) {
                String nextMarker = null;
                ObjectListing objectListing = null;
                do {
                    ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName)
                            .withPrefix(path)
                            .withMarker(nextMarker);

                    objectListing = client.listObjects(listObjectsRequest);
                    if (objectListing.getObjectSummaries().size() > 0) {
                        List<String> keys = new ArrayList<>();
                        for (OSSObjectSummary s : objectListing.getObjectSummaries()) {
                            System.out.println("key name: " + s.getKey());
                            keys.add(s.getKey());
                        }
                        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName).withKeys(keys);
                        client.deleteObjects(deleteObjectsRequest);
                    }

                    nextMarker = objectListing.getNextMarker();
                } while (objectListing.isTruncated());
            } else {
                System.out.println("要删除的文件： " + path);
                moveRecycle(path, userId);
                client.deleteObject(bucketName, path);

            }


        }


    }

    /**
     * 将文件复制到用户的回收站目录
     * @param path
     * @param userId
     */
    private void moveRecycle(String path, String userId) {
        String name = path.substring(path.lastIndexOf("/") + 1, path.length());
        String recyclyPath = basePath + userId + "/回收站/" + name;
        System.out.println("删除的文件" + path);
        System.out.println("回收站" + recyclyPath);
        client.copyObject(bucketName, path, bucketName, recyclyPath);

    }

    public void moveFile(List<String> paths, String targetPath, String userId) {
        targetPath = basePath + targetPath;
        for (int i = 0; i < paths.size(); i++) {
            String filePath = userId + paths.get(i);
            String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
            client.copyObject(bucketName, basePath + filePath, bucketName, targetPath + fileName);
            //复制完毕后将原文件删除。
            List<String> list = new ArrayList<>();
            list.add(filePath);
            deleteFile(list, userId);
        }

    }

    /**
     * 移动文件夹
     * @param path
     */
    public void mkDir(String path) {
        path = basePath + path;
        byte[] bytes = new byte[0];
        client.putObject(bucketName, path, new ByteArrayInputStream(bytes));
    }

    /**
     * 获取指定用户全部文件
     * @param userId
     * @return
     */
    public List<OSSObjectSummary> getAllFileList(String userId) {
        String path = basePath;
        if (!userId.equals("0")) {
            path += userId + "/";
        }
        final int maxKeys = 1000;
        ObjectListing objectListing = client.listObjects(
                new ListObjectsRequest(bucketName)
                        .withMaxKeys(maxKeys).withPrefix(path));


        return objectListing.getObjectSummaries();
    }

    /**
     * 下载文件
     * <p>返回文件下载的直链</p>
     * @param userId
     * @param path
     * @return
     */
    public String downloadFile(String userId, String path) {
        if (userId != null) {
            path = basePath + userId + path;
        }
        GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName, path, HttpMethod.GET);
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        urlRequest.setExpiration(expiration);
        String fileUrl = client.generatePresignedUrl(urlRequest).toString();
        String fileName = path.substring(path.lastIndexOf("/") + 1, path.length());

        return new down_ret(fileUrl, fileName).toJson();


    }

    public void reNameFile(String userId, String path, String name, String newName) {
        path = basePath + userId + path;
        client.copyObject(bucketName, path + name, bucketName, path + newName);
        client.deleteObject(bucketName, path + name);

    }

    private String[] getFileTypeArr(String format) {
        switch (format) {
            case "image":
                return new String[]{"jpg", "jpeg", "png", "bmp", "gif"};
            case "mp3":
                return new String[]{"mp3", "wav", "aif"};
            case "mp4":
                return new String[]{"mp4", "avi", "wmv"};
            case "text":
                return new String[]{"txt", "doc", "docx"};

        }
        return new String[]{};

    }

    public void deleteFile_(String path) {
        client.deleteObject(bucketName, basePath + path);


    }


}
